package org.cu.ooad.finalproject.layar;

import java.util.ArrayList;
import java.util.List;

import com.google.appengine.repackaged.org.json.JSONArray;

public class Map {

	private IOAdapter ioAdapter;
	private MapAdapter mapAdapter;
	private List<POI> POIs;

	public Map() {
		ioAdapter = new FileIO("WEB-INF/BuildingsDatabase.txt");
		mapAdapter = new MapAdapter();
		POIs = new ArrayList<POI>();
		constructPOIs();
	}

	/**
	 * Calculate distance (meters) between two points
	 * 
	 * @param lat1
	 * @param lon1
	 * @param lat2
	 * @param lon2
	 * @return
	 */
	private static double calcDistance(double lat1, double lon1, double lat2,
			double lon2) {
		double radius = 6371000.0; // mean radius of earth (m)
		double deltaLat = Math.toRadians(lat2 - lat1);
		double deltaLon = Math.toRadians(lon2 - lon1);
		double a = Math.sin(deltaLat / 2.0) * Math.sin(deltaLat / 2.0)
				+ Math.cos(Math.toRadians(lat1))
				* Math.cos(Math.toRadians(lat2)) * Math.sin(deltaLon / 2.0)
				* Math.sin(deltaLon / 2.0);
		double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
		return radius * c;
	}

	public JSONArray getPOIs() {
		JSONArray array = new JSONArray();
		for (int i = 0; i < POIs.size(); i++) {
			array.put(POIs.get(i).getJSON());
		}
		return array;
	}

	public JSONArray getPOIsInRange(double lat, double lon, double radius) {
		JSONArray array = new JSONArray();
		POI poi = null;
		for (int i = 0; i < POIs.size(); i++) {
			poi = POIs.get(i);
			if (calcDistance(poi.getLat(), poi.getLon(), lat, lon) < radius) {
				array.put(poi.getJSON());
			}
		}
		return array;
	}

	public String getNearestAddress(POI p) {
		return mapAdapter.getPOIAddress(p);
	}

	public MapAdapter getMapAdapter() {
		return mapAdapter;
	}

	public void setMapAdapter(MapAdapter mapAdapter) {
		this.mapAdapter = mapAdapter;
	}

	/**
	 * Construct the list of points of interest
	 */
	private void constructPOIs() {
		List<POI> poiList = ioAdapter.getAllPOIs();
		POI tempPOI = null;
//		String address = null;
		if (poiList==null) return;
		for (int i = 0; i < poiList.size(); i++) {
			tempPOI = poiList.get(i);
//			address = this.getNearestAddress(tempPOI);
//			if (address != null) {
//				String[] tokens = address.split(",");
//				if (tokens != null) {
//					if (tokens.length>0) {
//						tempPOI.setLine2(tokens[0]);
//					} else if (tokens.length>1) {
//						tempPOI.setLine3(tokens[1]);
//					} else if (tokens.length>2) {
//						tempPOI.setLine4(tokens[2]);
//					}
//				}
//			}
			POIs.add(tempPOI);
		}
	}
}
